#include "engine.h"
#include <iostream>

#include "core/window/window-mgr.h"
#include "core/asset/asset-mgr.h"
#include "core/utils/time.h"
#include "core/renderer/scene.h"
#include "core/global/renderer.h"
#include "core/gfx/gfx-mgr.h"
#include "core/font/freetype-mgr.h"




Engine::Engine()
{
    this->_frameRate = 30;
}
void Engine::init()
{
    this->_deltaTime = Time::nowTime();
    // 初始化窗口
    this->_initWindow();
    // 初始化 Vulkan
    this->_initGFX();
    // 初始化字体
    this->_initFont();
    // 初始化资产管理器
    this->_initAssetMgr();
}
void Engine::_initWindow()
{
    std::cout << "INIT WINDOW" << std::endl;
    WindowMgr::getInstance()->init();
}
void Engine::_initGFX()
{
    std::cout << "INIT GFX" << std::endl;
    GfxMgr::getInstance()->init();
}
void Engine::_initFont()
{
    std::cout << "INIT FONT" << std::endl;
    FreetypeMgr::getInstance()->init();
}

void Engine::_initAssetMgr()
{
    std::cout << "INIT ASSET MGR" << std::endl;
    AssetMgr::getInstance()->init();
}


/**
 * @brief 主循环
 */
void Engine::tick()
{
    this->_startRendererThread();
    // 窗口帧循环
    WindowMgr::getInstance()->tick();
    this->_stopRendererThread();
}
void Engine::_startRendererThread()
{
    this->_isRenderering = true;
    this->_renderThread = std::thread(&Engine::_updateRendererLoop, this); // 启动渲染线程
}
void Engine::_stopRendererThread()
{
    this->_isRenderering = false;
    if (this->_renderThread.joinable())
    {
        this->_renderThread.join(); // 等待线程结束
    }
}
void Engine::_updateRendererLoop()
{
    while (this->_isRenderering)
    {
        long deltaTime = Time::nowTime();
        long t = deltaTime - this->_deltaTime;
        if (t > 1000 / this->_frameRate)
        {
            this->update(t / 1000.0f);
            this->_deltaTime = deltaTime;
        }
    }
}
/**
 * @brief 引擎更新
 */
void Engine::update(float dt)
{
    Renderer::renderers.clear();
    // 更新场景
    if (this->_curScene)
    {
        this->_curScene->update(dt);
    }

    // 更新渲染器
    GfxMgr::getInstance()->update(Renderer::renderers);
}
void Engine::launch()
{
    std::cout << "launch engine" << std::endl;
}

/**
 * @brief 打开场景
 *
 * @param sceneName
 */
Scene *Engine::openScene(std::string sceneName)
{
    this->_curScene = new Scene(sceneName);
    return this->_curScene;
}

Engine::~Engine()
{
}
